# koroFileHeader at Yungoal acer
# Create: 2023-10-20 09:08:51
# LastEdit: 2023-10-26 17:36:19
"""说明暂无"""
__author__ = '749B'

from functools import reduce

from django.contrib import admin

# pylint: disable=import-error
from tasks.sync_resource_groups import SyncResourceGroups
from tasks.sync_resources import SyncResources

from . import models
# Register your models here.
def add_deploy_action(admin_class, task_class):
    """为admin_class添加任务的action
    使用归约函数完成多个任务的添加
    任务的动作是通用的，采用猴子补丁的方式在这里统一为需要的类加上任务的方法。

    解决action要从tasks导入导致的循环导入问题:
        tasks 导入 models
        admin 导入 models, tasks
        models 处于最底层不能导入上层的 tasks和admin
        现在admin放到了models下也要导入tasks就会导致循环导入
        只有admin的action才需要导入tasks, 把action的部分仍旧放在admin中, 避免循环导入
    """
    count = len(admin_class.actions)

    if f'task_{count}' not in admin_class.actions:
        admin_class.actions = list(admin_class.actions) + [f'task_{count}']

    @admin.display(description=f'任务状态[{count}]: {task_class.__name__}')
    def task_status(_, obj):
        return task_class.get_task_status(task_class.__name__, obj.name)

    @admin.action(description=f'执行任务[{count}]: {task_class.__name__}')
    def task(self, request, queryset):
        # 在执行任务后，才会添加任务状态显示
        if f'task_status_{count}' not in admin_class.list_display:
            admin_class.list_display = [
                i for i in admin_class.list_display if not i.startswith('task_status_')
                ] + [f'task_status_{count}']

        for query in queryset:
            task = task_class(query)
            task_started = task.start()
            if task_started:
                self.message_user(request, f'任务开始执行: {query}', 'success')
            else:
                self.message_user(
                    request,
                    f'任务未开始: {query} {task.task_start_msg or ""}', 
                    'warning')

    setattr(admin_class, f'task_status_{count}', task_status)
    setattr(admin_class, f'task_{count}', task)
    return admin_class


admin.site.register(models.Customer, models.CustomerAdmin)
admin.site.register(models.Account, reduce(add_deploy_action, [
    models.AccountAdmin, SyncResourceGroups, SyncResources]))
admin.site.register(models.User, models.UserAdmin)

admin.site.register(models.ResourceGroup, models.ResourceGroupAdmin)
admin.site.register(models.Resource, models.ResourceAdmin)

admin.site.register(models.TagKey, models.TagKeyAdmin)
